package com.albert.View;

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.albert.iotcar.R;


public class SideSlideView extends FrameLayout {
    public enum Direction {
        LEFT(0),
        RIGHT(1),
        TOP(2),
        BOTTOM(3);
        private final int value;
        Direction(int value) {
            this.value = value;
        }
        public int getValue() {
            return value;
        }
        // 工具方法：根据 int 找到对应枚举
        public static Direction fromInt(int value) {
            for (Direction sf : Direction.values()) {
                if (sf.value == value) {
                    return sf;
                }
            }
            return LEFT; // 默认值
        }
    }

    public interface OnSlideStateCallBack {
        void onSlideOpened();
        void onSlideClosed();
    }
    private OnSlideStateCallBack listener;

    public void setOnSlideStateCallBack(OnSlideStateCallBack listener) {
        this.listener = listener;
    }
    private ViewGroup slideContainer;
    private ImageView dragButton;
    private float dX;
    private float startX;

    private float startY;
    private boolean isDragging = false;
    private final float CLICK_THRESHOLD = 10f;

    public boolean isSideViewOpen = false;

    private int animationDuration = 300; // 默认动画时长
    private Direction slideFrom = Direction.LEFT; // 默认左边
    private int slideContentSpace;
    private int screenWidth, screenHeight;
    private int dragBtnWidth, dragBtnHeight;
    private int dragBtnImgSrc = -1; // 图片Id
    private float alpha = 1; // 默认 1
    private boolean enableShadow = true;
    private boolean moveUpAutoOpenClose = false;

    public SideSlideView(@NonNull Context context) {
        super(context);
        init(context, null);
    }

    public SideSlideView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public SideSlideView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        screenWidth = Resources.getSystem().getDisplayMetrics().widthPixels;
        screenHeight = Resources.getSystem().getDisplayMetrics().heightPixels;

        // 读取自定义属性
        if (attrs != null) {
            TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.SideSlideView);
            animationDuration = ta.getInt(R.styleable.SideSlideView_slideDuration, 300);
            slideContentSpace = ta.getDimensionPixelSize(R.styleable.SideSlideView_slideContentSpace, 200);
            dragBtnWidth = ta.getDimensionPixelSize(R.styleable.SideSlideView_dragBtnWidth, 40);
            dragBtnHeight = ta.getDimensionPixelSize(R.styleable.SideSlideView_dragBtnHeight, 50);
            moveUpAutoOpenClose = ta.getBoolean(R.styleable.SideSlideView_MoveUpAutoOpenClose,false);
            int direction = ta.getInt(R.styleable.SideSlideView_slideFrom, 0); // 默认 左边
            slideFrom = Direction.fromInt(direction);
            alpha = ta.getFloat(R.styleable.SideSlideView_alpha, 1);
            enableShadow = ta.getBoolean(R.styleable.SideSlideView_enableShadow, true);
            dragBtnImgSrc = ta.getResourceId(R.styleable.SideSlideView_dragBtnImgSrc, -1);

            ta.recycle();
        }
        // 加载内部布局
        LayoutInflater.from(context).inflate(R.layout.layout_side_slide, this, true);
        slideContainer = findViewById(R.id.side_view);
        dragButton = findViewById(R.id.drag_button);
        slideContainer.setVisibility(View.VISIBLE);
        applyShadow(context); // 根据方向自动加阴影
    }
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        float density = getResources().getDisplayMetrics().density;

        // 1️⃣ 确保 SideSlideView 自身宽高正确
        post(() -> {
            ViewGroup.LayoutParams parentLp = getLayoutParams();
            if (parentLp != null) {
                parentLp.width = ViewGroup.LayoutParams.MATCH_PARENT;
                parentLp.height = ViewGroup.LayoutParams.MATCH_PARENT;
                setLayoutParams(parentLp);
            }
        });

        // 2️⃣ 设置 slideContainer 背景和尺寸
        GradientDrawable bg = new GradientDrawable();
        bg.setColor(Color.WHITE);
        slideContainer.setBackground(bg);
        slideContainer.getBackground().setAlpha((int) (alpha * 255));

        LayoutParams slideLp = (LayoutParams) slideContainer.getLayoutParams();
        if (slideFrom == Direction.LEFT || slideFrom == Direction.RIGHT) {
            slideLp.width = slideContentSpace;
            slideLp.height = ViewGroup.LayoutParams.MATCH_PARENT;
            slideLp.gravity = (slideFrom == Direction.LEFT ? Gravity.LEFT : Gravity.RIGHT) | Gravity.CENTER_VERTICAL;
        } else {
            slideLp.width = ViewGroup.LayoutParams.MATCH_PARENT;
            slideLp.height = slideContentSpace;
            slideLp.gravity = (slideFrom == Direction.TOP ? Gravity.TOP : Gravity.BOTTOM) | Gravity.CENTER_HORIZONTAL;
        }
        slideContainer.setLayoutParams(slideLp);

        // 3️⃣ 设置 dragButton 尺寸和位置
        int dragBtnWidthPx = (int) (dragBtnWidth * density);
        int dragBtnHeightPx = (int) (dragBtnHeight * density);

        LayoutParams dragLp = new LayoutParams(dragBtnWidthPx, dragBtnHeightPx);
        if (slideFrom == Direction.LEFT || slideFrom == Direction.RIGHT) {
            dragLp.gravity = (slideFrom == Direction.LEFT ? Gravity.LEFT : Gravity.RIGHT) | Gravity.CENTER_VERTICAL;
        } else {
            dragLp.gravity = (slideFrom == Direction.TOP ? Gravity.TOP : Gravity.BOTTOM) | Gravity.CENTER_HORIZONTAL;
        }
        dragButton.setLayoutParams(dragLp);

        // 设置 dragButton 背景或图片
        if (dragBtnImgSrc != -1) {
            dragButton.setImageResource(dragBtnImgSrc);
        } else {
            GradientDrawable btnBg = new GradientDrawable();
            btnBg.setShape(GradientDrawable.RECTANGLE);
            btnBg.setCornerRadius(Math.min(dragBtnWidthPx, dragBtnHeightPx) / 2f);
            btnBg.setColor(0x99FF0000); // 红色更明显
            dragButton.setBackground(btnBg);
            dragButton.setElevation(20 * density);
        }

        // 4️⃣ 设置 dragButton 初始位置（必须使用 post 确保测量完成）
        dragButton.post(() -> {
            switch (slideFrom) {
                case LEFT:
                    slideContainer.setTranslationX(-slideContainer.getWidth());
                    dragButton.setX(0);
                    break;
                case RIGHT:
                    slideContainer.setTranslationX(slideContainer.getWidth());
                    dragButton.setX(getWidth() - dragButton.getMeasuredWidth());
                    break;
                case TOP:
                    slideContainer.setTranslationY(-slideContainer.getHeight());
                    dragButton.setY(0);
                    break;
                case BOTTOM:
                    slideContainer.setTranslationY(slideContainer.getHeight());
                    dragButton.setY(getHeight() - dragButton.getMeasuredHeight());
                    break;
            }
        });

        // 5️⃣ 设置拖动监听
        dragButton.setOnTouchListener(this::onDragTouch);

        // 6️⃣ 添加阴影（可选）
        applyShadow(getContext());
    }
    @Override
    public void addView(View child, int index, ViewGroup.LayoutParams params) {

        // 拖动按钮或已经在 slideContainer 内直接添加到父类
        if (child.getParent() == slideContainer) {
            super.addView(child, index, params);
        } else if (child.getId() == R.id.drag_button) {

        } else {
            // 其它元素自动添加到 slideContainer
            slideContainer.addView(child, params);
        }
    }

    /** 动态添加子元素到侧滑视图 */
    public void addSlideChild(View view) {
        slideContainer.addView(view);
    }

    /**
     * 设置拖动按钮图标
     * @param drawableId Drawable资源ID
     */
    public void setDragButtonIcon(int drawableId) {
        dragButton.setImageResource(drawableId);
    }
    /**
     * 设置拖动按钮图标
     * @param drawable Drawable对象
     */
    public void setDragButtonIcon(Drawable drawable) {
        dragButton.setImageDrawable(drawable);
    }

    private boolean onDragTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                dX = v.getX() - event.getRawX();
                startX = event.getRawX();
                startY = event.getRawY() - dragButton.getY();
                isDragging = false;
                return true;

            case MotionEvent.ACTION_MOVE:
                float moveX = event.getRawX();
                float deltaX = Math.abs(moveX - startX);

                if (deltaX > CLICK_THRESHOLD) {
                    isDragging = true;
                }

                if (isDragging) {
                    if (slideFrom == Direction.LEFT) { // LEFT
                        float newX = moveX + dX;
                        newX = Math.max(0, Math.min(slideContainer.getWidth(), newX)); // 限制范围
                        float percent = newX / slideContainer.getWidth(); // 0 ~ 1
                        slideContainer.setTranslationX(-slideContainer.getWidth() * (1 - percent)); // 0 对应隐藏，1 对应展开
                        dragButton.setX(newX);

                    } else if (slideFrom == Direction.RIGHT) { // RIGHT
                        float maxX = screenWidth - dragButton.getWidth();
                        float minX = maxX - slideContainer.getWidth();
                        float newX = Math.max(minX, Math.min(maxX, moveX + dX));
                        float percent = (maxX - newX) / slideContainer.getWidth(); // 0 ~ 1
                        slideContainer.setTranslationX(slideContainer.getWidth() * (1 - percent));
                        dragButton.setX(maxX - percent * slideContainer.getWidth());

                    } else if (slideFrom == Direction.TOP) { // TOP
                        float moveY = event.getRawY() - startY;  // 考虑起点偏移
                        float maxY = slideContainer.getHeight(); // 最大拖动距离
                        float newY = Math.max(0, Math.min(maxY, moveY));
                        float percent = newY / slideContainer.getHeight(); // 0 ~ 1
                        slideContainer.setTranslationY(-slideContainer.getHeight() + slideContainer.getHeight() * percent);
                        dragButton.setY(newY);

                    } else if (slideFrom == Direction.BOTTOM) { // BOTTOM
                        float moveY = event.getRawY() - startY;
                        float maxY = screenHeight - dragButton.getHeight();
                        float minY = maxY - slideContainer.getHeight();
                        float newY = Math.max(minY, Math.min(maxY, moveY));
                        float percent = (maxY - newY) / slideContainer.getHeight(); // 0 ~ 1
                        slideContainer.setTranslationY(slideContainer.getHeight() * (1 - percent));
                        dragButton.setY(maxY - percent * slideContainer.getHeight());

                    }
                }
                return true;

            case MotionEvent.ACTION_UP:
                if (!moveUpAutoOpenClose) {
                    followMoveStop();
                } else {
                    upAutoOpenClose();
                }

                return true;
        }
        return false;
    }

    private void followMoveStop() {
        if (!isDragging) {
            // 点击按钮 → 视图弹出或收回
            float targetPercent = isSideViewOpen ? 0f : 1f;
            switch (slideFrom) {
                case LEFT:
                    slideContainer.animate()
                            .translationX(-slideContainer.getWidth()* (1 - targetPercent))
                            .setDuration(300)
                            .start();
                    dragButton.animate()
                            .x(targetPercent * slideContainer.getWidth())
                            .setDuration(300)
                            .start();
                    break;
                case RIGHT:
                    slideContainer.animate()
                            .translationX(slideContainer.getWidth() * (1 - targetPercent))
                            .setDuration(300)
                            .start();
                    float buttonTargetX = screenWidth - dragButton.getWidth() - targetPercent * slideContainer.getWidth();
                    dragButton.animate()
                            .x(buttonTargetX)
                            .setDuration(300)
                            .start();
                    break;
                case TOP:
                    slideContainer.animate()
                            .translationY(-slideContainer.getHeight()* (1 - targetPercent))
                            .setDuration(300)
                            .start();
                    dragButton.animate()
                            .y(slideContainer.getHeight() * targetPercent)
                            .setDuration(300)
                            .start();
                    break;
                case BOTTOM:
                    slideContainer.animate()
                            .translationY( slideContainer.getHeight() * (1 - targetPercent))
                            .setDuration(300)
                            .start();
                    float buttonTargetY = screenHeight - dragButton.getHeight() - targetPercent * slideContainer.getHeight();
                    dragButton.animate()
                            .y(buttonTargetY)
                            .setDuration(300)
                            .start();
                    break;
                default: break;
            }

            isSideViewOpen = !isSideViewOpen;

            if (listener != null) {
                if (isSideViewOpen) {
                    listener.onSlideOpened();
                } else {
                    listener.onSlideClosed();
                }
            }
        }
    }

    private void upAutoOpenClose() {
        if (!isDragging) {
            toggle();
        } else {
            if (slideFrom == Direction.LEFT) { // LEFT
                if (dragButton.getX() > slideContainer.getWidth() / 2f) {
                    open();
                } else {
                    close();
                }
            } else if (slideFrom == Direction.RIGHT){ // RIGHT
                float maxX = screenWidth - dragButton.getWidth();
                if (dragButton.getX() < maxX - slideContainer.getWidth() / 2f) {
                    open();
                } else {
                    close();
                }
            } else if (slideFrom == Direction.TOP) { // TOP
                if (dragButton.getY() > slideContainer.getHeight() / 2f) {
                    open();
                } else {
                    close();
                }
            } else if (slideFrom == Direction.BOTTOM) { // BOTTOM
                float maxY = screenHeight - dragButton.getHeight();
                if (dragButton.getY() < maxY - slideContainer.getHeight() / 2f) {
                    open();
                } else {
                    close();
                }
            }
        }
    }


    /** 打开 */
    public void open() {
        animateToPercent(1f);
        isSideViewOpen = true;

        if (listener != null) {
            listener.onSlideOpened();
        }
    }

    /** 关闭 */
    public void close() {
        animateToPercent(0f);
        isSideViewOpen = false;

        if (listener != null) {
            listener.onSlideClosed();
        }
    }

    /** 切换 */
    public void toggle() {
        if (isSideViewOpen) {
            close();
        } else {
            open();
        }
    }

    private void animateToPercent(float percent) {
        float sw = slideContainer.getWidth();
        float sh = slideContainer.getHeight();
        float bw = dragButton.getWidth();
        float bh = dragButton.getHeight();

        switch (slideFrom) {
            case LEFT: // LEFT
                slideContainer.animate().translationX(-sw * (1 - percent)).setDuration(animationDuration).start();
                dragButton.animate().x(sw * percent).setDuration(animationDuration).start();
                break;
            case RIGHT: // RIGHT
                slideContainer.animate().translationX(sw * (1 - percent)).setDuration(animationDuration).start();
                float bxR = screenWidth - bw - sw * percent;
                dragButton.animate().x(bxR).setDuration(animationDuration).start();
                break;
            case TOP: // TOP
                slideContainer.animate().translationY(-sh * (1 - percent)).setDuration(animationDuration).start();
                dragButton.animate().y(sh * percent).setDuration(animationDuration).start();
                break;
            case BOTTOM: // BOTTOM
                slideContainer.animate().translationY(sh * (1 - percent)).setDuration(animationDuration).start();
                float byB = screenHeight - bh - sh * percent;
                dragButton.animate().y(byB).setDuration(animationDuration).start();
                break;
        }
    }

    private void applyShadow(Context context) {
        if (slideContainer == null || !enableShadow) return;

        ShadowLayout shadowLayout = null;
        LayoutParams lp = null;
        if (slideFrom == Direction.LEFT || slideFrom == Direction.RIGHT) {
            float dx = slideFrom == Direction.LEFT ? -30 : 20;
            shadowLayout = new ShadowLayout(context, dx, 0);
            if (slideFrom == Direction.RIGHT) {
                lp = new LayoutParams(40, ViewGroup.LayoutParams.MATCH_PARENT);
                lp.setMargins(-15, 0, 0, 0); // 上、左、右、下边距
            } else {
                lp = new LayoutParams(30, ViewGroup.LayoutParams.MATCH_PARENT);
                lp.setMargins(0, 0, 0, 0); // 上、左、右、下边距
            }
            lp.gravity = slideFrom == Direction.LEFT ? Gravity.END : Gravity.START;
            lp.gravity = lp.gravity | Gravity.CENTER_VERTICAL;
        } else {
            float dy = slideFrom == Direction.TOP ? -30 : 15;
            shadowLayout = new ShadowLayout(context, 0, dy);
            if (slideFrom == Direction.BOTTOM) {
                lp = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 30);
                lp.setMargins(0, -10, 0, 0); // 上、左、右、下边距
            } else {
                lp = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 30);
                lp.setMargins(0, 0, 0, 0); // 上、左、右、下边距
            }
            lp.gravity = slideFrom == Direction.TOP ? Gravity.BOTTOM : Gravity.TOP;
            lp.gravity = lp.gravity | Gravity.CENTER_HORIZONTAL;
        }
        shadowLayout.setLayoutParams(lp);
        addView(shadowLayout);
    }

    private int dp2px(int dp) {
        return (int) (dp * getResources().getDisplayMetrics().density);
    }
}
